# 第06章 Maven构架SSM工程

# 6.1 需求

实现SSM工程构建,规范依赖管理。场景:根据id展示商品信息

# 6.2 准备数据库

/*
Navicat MySQL Data Transfer

Source Server         : localhost_3306
Source Server Version : 50096
Source Host           : localhost:3306
Source Database       : maven_ssm

Target Server Type    : MYSQL
Target Server Version : 50096
File Encoding         : 65001

Date: 2018-04-23 14:07:06
*/

SET FOREIGN_KEY_CHECKS=0;
-- ----------------------------
-- Table structure for `items`
-- ----------------------------
DROP TABLE IF EXISTS `items`;
CREATE TABLE `items` (
  `id` int(10) NOT NULL auto_increment,
  `name` varchar(20) default NULL,
  `price` float(10,0) default NULL,
  `pic` varchar(40) default NULL,
  `createtime` datetime default NULL,
  `detail` varchar(200) default NULL,
  PRIMARY KEY  (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=9 DEFAULT CHARSET=utf8;

-- ----------------------------
-- Records of items
-- ----------------------------
INSERT INTO `items` VALUES ('1', '重庆出品', '1000', null, '2018-03-13 09:29:30', '带我走上人生巅峰');
INSERT INTO `items` VALUES ('2', '重庆310', null, null, '2018-03-28 10:05:52', '插入测试');
INSERT INTO `items` VALUES ('3', '重庆307', '199', null, '2018-03-07 10:08:04', '插入测试');
INSERT INTO `items` VALUES ('7', '插入测试', null, null, null, null);
INSERT INTO `items` VALUES ('8', '插入测试', null, null, null, null);
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38

# 6.3 创建Maven工程

新建一个ssm_maven项目,使用下图选中的骨架

1555841521589

下一步填写坐标

1555841555843

查看是否使用的自己的私服

1555841567960

在main目录下新建 java和resources文件夹

1555841588085

把java和resources文件夹转成source root

1555841608720

修改编译版本,在pom.xml文件中添加

<build>
    <plugins>
      <!-- 设置编译版本为1.8 -->
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-compiler-plugin</artifactId>
        <version>3.1</version >
        <configuration>
          <source>1.8</source>
          <target>1.8</target>
          <encoding>UTF-8</encoding>
        </configuration>
      </plugin>
    </plugins>
</build>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

# 6.4 依赖

# 6.4.1 什么是依赖传递

先添加springmvc的核心依赖的坐标

<dependencies>
  <dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-webmvc</artifactId>
    <version>4.2.4.RELEASE</version>
  </dependency>
</dependencies>
1
2
3
4
5
6
7

会发现出现除了spring-webmvc以外的其他jar。因为我们的项目依赖spring-webmv.jar,而spring-webmv.jar会依赖spring-beans.jar等等,所以spring-beans.jar这些jar包也出现在了我们的maven工程中,这种现象我们称为依赖传递。从下图中可看到他们的关系:(请注意spring-beans的版本)

1555841767445

# 6.4.2 依赖冲突的解决

接着添加一个依赖5.0.2.RELEASE版本的spring-context

1555841841343

我们会发现这两个jar包同时都依赖了spring-beans

1555841856870

但是spring-webmvc依赖spirng-beans-4.2.4,spring-context依赖spring-beans-5.0.2,但是发现spirng-beans-4.2.4加入到工程中

1555841953869

而我们希望spring-beans-5.0.2加入工程。这就造成了依赖冲突。解决依赖冲突有以下原则:

# 依赖调解原则

maven自动按照下边的原则调解:

  • 第一声明者优先原则

在pom文件定义依赖,先声明的依赖为准。 测试:如果将上边spring-webmvc和spring-context顺序颠倒,系统将导入spring-beans-5.0.2。 分析:由于spring-webmvc在前边以spring-webmvc依赖的spring-beans-5.0.2为准,所以最终spring-beans-5.0.2添加到了工程中。

  • 路径近者优先原则

例如:还是上述情况,spring-contex和spring-webmvc都会传递过来 spirng-beans,那如果直接把spring-beans的依赖直接写到pom文件中,那么项目就不会再使用其他依赖传递来的spring-beans,因为自己直接在pom中定义spring-beans要比其他依赖传递过来的路径要近。

在本工程中的pom中加入spirng-beans-5.0.2的依赖,根据路径近者优先原则,系统将导入spirng-beans-5.0.2

1555842116027\

# 排除依赖

上边的问题也可以通过排除依赖方法辅助依赖调解,如下:

比如在依赖spring-webmvc的设置中添加排除依赖,排除spring-beans,下边的配置表示:依赖spring-webmvc,但排除spring-webmvc所依赖的spring-beans。

1555842160607

# 锁定版本

面对众多的依赖,有一种方法不用考虑依赖路径、声明优化等因素可以采用直接锁定版本的方法确定依赖构件的版本,版本锁定后则不考虑依赖的声明顺序或依赖的路径,以锁定的版本的为准添加到工程中,此方法在企业开发中常用。

如下的配置是锁定了spring-beans和spring-context的版本:

1555842187769

还可以把版本号提取出来,使用<properties>标签设置成变量。

1555842210227

注意:在工程中锁定依赖的版本并不代表在工程中添加了依赖,如果工程需要添加锁定版本的依赖则需要单独添加<dependencies></dependencies>标签,如下:

1555842259827

上边添加的依赖并没有指定版本,原因是已在<dependencyManagement>中锁定了版本,所以在<dependency>下不需要再指定版本。

# 6.5 pom.xml

maven工程首先要识别依赖,web工程实现SSM整合,需要依赖spring-webmvc5.0.2、 spring5.0.2、mybatis3.4.5等,在pom.xml添加工程如下依赖:

分两步:

1)锁定依赖版本

2)添加依赖

<?xml version="1.0" encoding="UTF-8"?>

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>cn.itcast.ssm_maven</groupId>
    <artifactId>ssm_maven</artifactId>
    <version>1.0-SNAPSHOT</version>
    <packaging>war</packaging>

    <properties>
        <spring.version>5.0.2.RELEASE</spring.version>
        <springmvc.version>5.0.2.RELEASE</springmvc.version>
        <mybatis.version>3.4.5</mybatis.version>
    </properties>

    <!--锁定依赖版本-->
    <dependencyManagement>
        <dependencies>
            <!-- Mybatis -->
            <dependency>
                <groupId>org.mybatis</groupId>
                <artifactId>mybatis</artifactId>
                <version>${mybatis.version}</version>
            </dependency>

            <!-- springMVC -->
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-webmvc</artifactId>
                <version>${springmvc.version}</version>
            </dependency>

            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-context</artifactId>
                <version>${spring.version}</version>
            </dependency>

            <!-- spring -->
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-core</artifactId>
                <version>${spring.version}</version>
            </dependency>

            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-aop</artifactId>
                <version>${spring.version}</version>
            </dependency>

            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-web</artifactId>
                <version>${spring.version}</version>
            </dependency>

            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-expression</artifactId>
                <version>${spring.version}</version>
            </dependency>

            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-beans</artifactId>
                <version>${spring.version}</version>
            </dependency>

            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-aspects</artifactId>
                <version>${spring.version}</version>
            </dependency>

            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-context-support</artifactId>
                <version>${spring.version}</version>
            </dependency>
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-test</artifactId>
                <version>${spring.version}</version>
            </dependency>
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-jdbc</artifactId>
                <version>${spring.version}</version>
            </dependency>
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-tx</artifactId>
                <version>${spring.version}</version>
            </dependency>
        </dependencies>
    </dependencyManagement>

    <!--添加依赖-->
    <dependencies>
        <!-- Mybatis和mybatis与spring的整合 -->
        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis</artifactId>
        </dependency>
        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis-spring</artifactId>
            <version>1.3.1</version>
        </dependency>

        <!-- MySql驱动 -->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.32</version>
        </dependency>

        <!-- druid数据库连接池 -->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid</artifactId>
            <version>1.0.9</version>
        </dependency>

        <!-- springMVC核心-->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-webmvc</artifactId>
        </dependency>

        <!-- spring相关 -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-core</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-aop</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-web</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-expression</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-beans</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-aspects</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context-support</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-test</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-jdbc</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-tx</artifactId>
        </dependency>
        <!-- junit测试 -->
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
        </dependency>

        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>servlet-api</artifactId>
            <version>2.5</version>
            <scope>provided</scope>
        </dependency>

        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>jsp-api</artifactId>
            <version>2.0</version>
            <scope>provided</scope>
        </dependency>

        <!-- jstl -->
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>jstl</artifactId>
            <version>1.2</version>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <!-- 设置编译版本为1.8 -->
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.1</version >
                <configuration>
                    <source>1.8</source>
                    <target>1.8</target>
                    <encoding>UTF-8</encoding>
                </configuration>
            </plugin>

            <plugin>
                <groupId>org.apache.tomcat.maven</groupId>
                <artifactId>tomcat7-maven-plugin</artifactId>
                <version>2.2</version>
                <configuration>
                    <path>/</path>
                    <port>8080</port>
                </configuration>
            </plugin>
        </plugins>
    </build>
</project>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239

# 6.6 DAO

src/main/java中定义dao接口,实现根据id 查询商品信息:

src/main/java创建模型类

1555842538246

配置文件

注意配置文件的位置

1555842665484

内容如下

<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" > 
<mapper namespace="cn.itcast.ssm.dao.ItemsMapper" > 
    <select id="findById" parameterType="int" resultType="items"> 
        select * from items where id=#{id} 
    </select>
</mapper>
1
2
3
4
5
6

src/main/resources创建applicationContext.xml

<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:context="http://www.springframework.org/schema/context" xmlns:p="http://www.springframework.org/schema/p" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd http://www.springframework.org/schema/context
    http://www.springframework.org/schema/context/spring-context-4.0.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.0.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.0.xsd http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-4.0.xsd"> 
    <!-- 数据库连接池 --> 
    <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource"> 
        <!-- 驱动 --> 
        <property name="driverClassName" value="com.mysql.jdbc.Driver" /> 
        <!-- url --> 
        <property name="url" value="jdbc:mysql://localhost:3306/maven" /> 
        <!-- 用户名 --> 
        <property name="username" value="root" /> 
        <!-- 密码 --> 
        <property name="password" value="root" /> 
    </bean> 
    <!-- mapper配置 --> 
    <!-- 让spring管理sqlsessionfactory 使用mybatis和spring整合包中的 --> 
    <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean"> 
        <!-- 数据库连接池 --> 
        <property name="dataSource" ref="dataSource" /> 
        <property name="typeAliasesPackage" value="cn.itcast.ssm.pojo">
        </property> 
    </bean> 
    <!-- mapper扫描器 :用来产生代理对象--> 
    <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer"> 
        <property name="basePackage" value="cn.itcast.ssm.dao">
        </property> 
    </bean> 
</beans>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27

src/main/resources配置log4j.properties

### direct log messages to stdout
log4j.appender.stdout=org.apache.log4j.ConsoleAppender 
log4j.appender.stdout.Target=System.out 
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout 
log4j.appender.stdout.layout.ConversionPattern=%d{ABSOLUTE} %5p %c{1}:%L - %m%n 
### set log levels - for more verbose logging change 'info' to 'debug' 
#在开发阶段日志级别使用debug 
log4j.rootLogger=debug, stdout 
### 在日志中输出sql的输入参数 
log4j.logger.org.hibernate.type=TRACE
1
2
3
4
5
6
7
8
9
10

单元测试

src/test/java创建单元测试类

public class ItemsMapperTest { 
    @Test 
    public void testFindItemsById() { 
        //获取spring容器 
        ApplicationContext applicationContext = new ClassPathXmlApplicationContext("classpath:applicationContext.xml"); 
        //获取Mapper ItemsMapper 
        itemsMapper = applicationContext.getBean(ItemsMapper.class); 
        //调用Mapper方法 
        Items items = itemsMapper.findById(1);
        System.out.println(items); 
    } 
}
1
2
3
4
5
6
7
8
9
10
11
12

# 6.7 Service

代码

@Service
public class ItemsServiceImpl implements ItemsService {

    @Autowired
    private ItemsMapper itemsMapper;
    @Override
    public Items findById(int itemId) {
        return itemsMapper.findById(itemId);
    }

}
1
2
3
4
5
6
7
8
9
10
11

配置文件

applicationContext.xml中配置service的扫面器

<context:component-scan base-package="cn.itcast.ssm.service"/>
1

# 6.8 Web

代码

@Controller
@RequestMapping("/items")
public class ItemsController {

   @Autowired
   private ItemsService itemsService ;
// 展示商品信息页面
   @RequestMapping("/showItem")  
    public String showItem(int id,Model model){
      Items items = itemsService.findById(id);
      model.addAttribute("item", items);
      return "viewItem";
   }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14

配置文件

springmvc.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:mvc="http://www.springframework.org/schema/mvc"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.2.xsd
        http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.2.xsd
        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.2.xsd">

    <context:component-scan base-package="cn.itcast.ssm.controller"></context:component-scan>

    <!--  配置视图解析器的前缀和后缀 -->
    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="prefix" value="/WEB-INF/jsp/"></property>
        <property name="suffix" value=".jsp"></property>
    </bean>
</beans>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17

Web.xml

加载spring容器,配置springmvc前端控制器

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" id="WebApp_ID" version="2.5">
  <!--   前端控制器 加载springmvc容器 -->
  <servlet>
    <servlet-name>springmvc</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <init-param>
      <param-name>contextConfigLocation</param-name>
      <param-value>classpath:springmvc.xml</param-value>
    </init-param>
  </servlet>
  <servlet-mapping>
    <servlet-name>springmvc</servlet-name>
    <url-pattern>*.action</url-pattern>
  </servlet-mapping>
  <!--     监听器 加载spring容器 -->
  <listener>
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
  </listener>
  <context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>classpath*:applicationContext*.xml</param-value>
  </context-param>
</web-app>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24

# 6.9 JSP

/WEB-INF/jsp/viewItem.jsp如下:

<%@ page language="java" contentType="text/html; charset=UTF-8"
         pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/fmt"  prefix="fmt"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    <title>商品信息</title>
</head>
<body>
<form>
    <table width="100%" border=1>
        <tr>
            <td>商品名称</td>
            <td> ${item.name } </td>
        </tr>
        <tr>
            <td>商品价格</td>
            <td> ${item.price } </td>
        </tr>
        <tr>
            <td>生成日期</td>
            <td> <fmt:formatDate value="${item.createtime}" pattern="yyyy-MM-dd HH:mm:ss"/> </td>
        </tr>
        <tr>
            <td>商品简介</td>
            <td>${item.detail} </textarea>
            </td>
        </tr>
    </table>
</form>
</body>
</html>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34

# 6.10 运行与调试

运行结果如下:

1555843201771

Last Updated: 10/20/2019, 11:49:45 PM